efImportFile = function(libraryName) {
    document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
}
efImportCSS = function(cssName) {
    document.write('<link href="' + cssName + '" rel="stylesheet" type="text/css"/>');
}

efImportFile(IPLATUI.CONTEXT_PATH +'/EW/mxGraph/mxClient.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/DomHelper.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Editor.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Graph.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Shapes.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Actions.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Menus.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Sidebar.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Toolbar.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Dialogs.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Nodes.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Translation.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/WfModel.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/js/Validation.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/bpm/WorkflowDesigner/jscolor/jscolor.js');
efImportFile(IPLATUI.CONTEXT_PATH +'/FormBuilder/js/Math.uuid.js');

//////////////////////////////////////
	// Public global variables
		var MAX_REQUEST_SIZE = 10485760;
		var MAX_WIDTH = 6000;
		var MAX_HEIGHT = 6000;
	
		// URLs for save and export
		mxBasePath = IPLATUI.CONTEXT_PATH+'/bpm/WorkflowDesigner';
		var EXPORT_URL = IPLATUI.CONTEXT_PATH+'/export';
		var SAVE_URL = IPLATUI.CONTEXT_PATH+'/save';
		var OPEN_URL = IPLATUI.CONTEXT_PATH+'/open';
		var RESOURCES_PATH =mxBasePath+ '/resources';
		var RESOURCE_BASE = RESOURCES_PATH + '/grapheditor';
		var STENCIL_PATH = mxBasePath+ '/stencils';
		var IMAGE_PATH = mxBasePath+ '/images';
		var STYLE_PATH = mxBasePath+ '/styles';
		var CONFIG_PATH = mxBasePath+ '/config';
		var CSS_PATH = mxBasePath+ '/styles';
		var OPEN_FORM = IPLATUI.CONTEXT_PATH+'open.html';
	
		// Specifies connection mode for touch devices (at least one should be true)
		var tapAndHoldStartsConnection = true;
		var showConnectorImg = true;

		// Parses URL parameters. Supported parameters are:
		// - lang=xy: Specifies the language of the user interface.
		// - touch=1: Enables a touch-style user interface.
		// - storage=local: Enables HTML5 local storage.
		var urlParams = (function(url)
		{
			var result = new Object();
			var idx = url.lastIndexOf('?');
	
			if (idx > 0)
			{
				var params = url.substring(idx + 1).split('&');
				
				for (var i = 0; i < params.length; i++)
				{
					idx = params[i].indexOf('=');
					
					if (idx > 0)
					{
						result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
					}
				}
			}
			
			return result;
		})(window.location.href);

		// Sets the base path, the UI language via URL param and configures the
		// supported languages to avoid 404s. The loading of all core language
		// resources is disabled as all required resources are in grapheditor.
		// properties. Note that in this example the loading of two resource
		// files (the special bundle and the default bundle) is disabled to
		// save a GET request. This requires that all resources be present in
		// each properties file since only one file is loaded.
		mxLoadResources = false;
		
	
		mxLanguage = urlParams['lang'];
		mxLanguages = ['zh'];
		
		var freshFlag="0";
		var viewer=null;
	
	
	////////////////////////////////////////


/**
 * Constructs a new workflow status viewer
 */
EditorUi = function(editor, container) {
	this.editor = editor || new Editor();
	this.container = container || document.body;
	var graph = editor.graph;
	var model = graph.getModel();

	// Disables scrollbars
	this.container.style.overflow = 'hidden';

	var textEditing = mxUtils.bind(this, function(evt) {
				if (evt == null) {
					evt = window.event;
				}

				if (this.isSelectionAllowed(evt)) {
					return true;
				}

				return graph.isEditing() || this.dialog != null;
			});
    // forbbiden right menu;
    $(document.body)[0].setAttribute('oncontextmenu','self.event.returnValue=false');
    //document.body.oncontextmenu =false;
	// Pre-fetches submenu image
	new Image().src = mxPopupMenu.prototype.submenuImage;

	// Pre-fetches connect image
	if (mxConnectionHandler.prototype.connectImage != null) {
		new Image().src = mxConnectionHandler.prototype.connectImage.src;
	}

	// Creates the user interface
	//this.actions = new Actions(this);
	//this.menus = new Menus(this);
	this.diagramContainer = this.createDiv('diagramContainer');
	this.diagramContainer.style.position = 'absolute';
	this.diagramContainer.style.overflow = 'auto';
	this.diagramContainer.style.width = '750px';
	this.diagramContainer.style.top = '60px';
	
	this.hintsContainer = this.createDiv('hintsContainer');
	this.sidebarContainer = this.createDiv('geSidebarContainer');
	this.outlineContainer = this.createDiv('geOutlineContainer')
	this.createSidebar(this.sidebarContainer);
	
	// /////////////////////////////	
	this.hintsContainer.appendChild(this.createHints());
    this.container.appendChild(this.diagramContainer);
	this.container.appendChild(this.hintsContainer);
	this.refresh();

	// /////////////////////////////////////////////////////////////////////

	// Adds automatic layout and various switches if the
	// graph is enabled
	if (graph.isEnabled()) {
		// Allows new connections but no dangling edges
		graph.setConnectable(true);
		graph.setAllowDanglingEdges(false);

		// End-states are no valid sources
		var previousIsValidSource = graph.isValidSource;

		graph.isValidSource = function(cell) {
			if (previousIsValidSource.apply(this, arguments)) {
				var style = this.getModel().getStyle(cell);

				return style == null
						|| !(style == 'end' || style.indexOf('end') == 0);
			}

			return false;
		};

		// Start-states are no valid targets, we do not
		// perform a call to the superclass function because
		// this would call isValidSource
		// Note: All states are start states in
		// the example below, so we use the state
		// style below
		graph.isValidTarget = function(cell) {
			var style = this.getModel().getStyle(cell);

			return !this.getModel().isEdge(cell)
					&& !this.isSwimlane(cell)
					&& (style == null || !(style == 'state' || style
							.indexOf('state') == 0));
		};

		// Adds new method for identifying a pool
					graph.isPool = function(cell)
					{
						var model = this.getModel();
						return this.isSwimlane(cell);
					};
		// Changes swimlane orientation while collapsed
		graph.model.getStyle = function(cell) {
			var style = mxGraphModel.prototype.getStyle.apply(this, arguments);

			if (graph.isCellCollapsed(cell)) {
				if (style != null) {
					style += ';';
				} else {
					style = '';
				}

				style += 'horizontal=1;align=left;spacingLeft=14;';
			}

			return style;
		};
		// overwrite dblclick
		var viewer = this;
		// 鼠标点击事件  
        graph.addListener(mxEvent.CHANGE, function(sender, evt)  
        {  
            var cell = evt.getProperty('cell');  
              
            if (cell != null)  
            {  
                var overlays = graph.getCellOverlays(cell);  
                  
                if (overlays == null)  
                {  
                    // 复写按钮图片  
                    var overlay = new mxCellOverlay(  
                        new mxImage(graph.warningImage, 16, 16),  
                        'Overlay tooltip');  

                    // 单击显示提示                     
                    overlay.addListener(mxEvent.CLICK, function(sender, evt2)  
                    {  
                        mxUtils.alert('Overlay clicked');  
                    });  
                      
                    // 在图形中覆盖  
                    graph.addCellOverlay(cell, overlay);  
                }  
                else  
                {  
                    graph.removeCellOverlays(cell);  
                }  
            }  
        });
        //捕获任务节点的鼠标点击事件
        graph.addListener(mxEvent.CLICK, function(sender, evt) {
            var cell = evt.getProperty('cell');
            if (graph.getModel().isEdge(cell)) return;
            if (!cell || !cell.value) return;
            var tagName = cell.value.tagName;
            var procInstId = cell.value.getAttribute("procInstId");
            var name = cell.value.getAttribute("Name");
            var instid = cell.value.getAttribute("instid");
            if (procInstId != null && name != null) {
                graph.tooltipHandler.hide();
                if (tagName == "SubProcess") {
                    var info = new EiInfo();
                    info.set('activityInstanceId', instid);
                    info.set('processInstanceId', procInstId);
                    info.set('instActivity', name);
                    EiCommunicator.send('EWPI00', 'getSubProcessInfoById', info, {
                        onSuccess: function (outInfo) {

                            var subProcessInstType = outInfo.get("subProcessInstType");
                            var processInstanceId = outInfo.get("processInstanceId");
                            var instActivity = outInfo.get("instActivity");
                            var options = {
                                'width': 1000,
                                'height': 580,
                                'params': 'efHeadTail=none&inqu_status-0-processInstanceId=' + procInstId
                            };
                            // if (subProcessInstType == 'multiInst')
                                IPLAT.openForm("EWPI04", "inqu_status-0-parentInstanceId=" + procInstId + "&inqu_status-0-instActivity=" + instActivity);
                            // else
                            //     IPLAT.openForm("EWPI02", "inqu_status-0-processInstanceId=" + processInstanceId);
                        },
                        onFail: function (message) {
                            alert(message);
                        }
                    }, false, false);

                }
                else if (tagName == "Manual") {
                    info = new EiInfo();
                    info.set('nodeKey', name);
                    info.set('processInstanceId', procInstId);
                    EiCommunicator.send('EWPI01', 'querySecrecy', info, {
                        onSuccess: function (outInfo) {
                            if ("true" == outInfo.get("secrecy")) {
                            } else {
                                var url = IPLATUI.CONTEXT_PATH + "/web/EWPI03?inqu_status-0-procInstId=" + procInstId + '&inqu_status-0-name=' + name;
                                var window = $("#window");
                                window.data("kendoWindow").setOptions({
                                    open: function () {
                                        window.data("kendoWindow").refresh({
                                            url: url
                                        });
                                    }
                                })
                                window.data("kendoWindow").content("");
                                //打开弹窗
                                window.data("kendoWindow").center();
                                window.data("kendoWindow").open();
                            }
                        },
                        onFail: function (message) {
                            alert(message);
                        }
                    }, false, true);
                } else if (tagName == "Service") {
                    var url = IPLATUI.CONTEXT_PATH + "/web/EWPI05?inqu_status-0-processInstanceId=" + procInstId + '&inqu_status-0-nodeKey=' + name;
                    var window = $("#window");
                    window.data("kendoWindow").setOptions({
                        open: function () {
                            window.data("kendoWindow").refresh({
                                url: url
                            });
                        }
                    })
                    window.data("kendoWindow").content("");
                    //打开弹窗
                    window.data("kendoWindow").open();
                }
            }
        });

        // graph.dblClick = function (evt, cell) {
        // };
        //设置导航图的任务节点的鼠标与移入移出效果
        var track = new mxCellTracker(graph);

        track.mouseMove = function(sender, me) {
            var cell = this.getCell(me);
            var self=this;
            if (cell && graph.getModel().isVertex(cell)) {
                //设置鼠标为样式为手状
                me.getState().setCursor('pointer');
            }
        };
		
		/////
		graph.getTooltipForCell = function(cell) {
			var tip = '';
			var SequenceId = '';
			if (this.isSwimlane(cell))
				return tip;
			if (cell.value && cell.value.nodeName) {
				var setting = cell.value;
				var name = setting.getAttribute('Name');
				//var instid = setting.getAttribute('instid');
				// 获取流程实例ID
				var procInstId = setting.getAttribute('procInstId');
				// 根据流程实例ID后台查询流程实例表 得到序列号

				if (procInstId!=null){
					var info =new EiInfo();
					info.set("ProcessInstanceId" ,procInstId);
					EiCommunicator.send('EWPI00', 'getSenquenceIdById', info, {
						onSuccess : function(outInfo) {
							SequenceId = outInfo.get('SequenceId');
							if(SequenceId==""){
								alert("流程没有绑定表单！");
								return;
							}
							return;
						},
						onFail : function(message) {
							alert(message);
						}
					}, false, false);
				}

				var startTime = setting.getAttribute('startTime');
				var endTime = setting.getAttribute('endTime');
				var duration = setting.getAttribute('duration');
				var state = setting.getAttribute('state');
				if (procInstId != null) {
					tip += '状态:' + state + "\n";
					tip += '开始时间:' + startTime + "\n";
					tip += '结束时间:' + endTime + "\n";
					tip += '持续时间:' + duration + "\n";
				}
			}
			return tip;
		};

		// Keeps widths on collapse/expand
		var foldingHandler = function(sender, evt) {
			var cells = evt.getProperty('cells');

			for (var i = 0; i < cells.length; i++) {
				var geo = graph.model.getGeometry(cells[i]);

				if (geo.alternateBounds != null) {
					geo.width = geo.alternateBounds.width;
				}
			}
		};

		graph.addListener(mxEvent.FOLD_CELLS, foldingHandler);
	}
	
	graph.setCellWarning=function(cell, warning, img, isSelect){
		
	}

	// Applies size changes to siblings and parents
	new mxSwimlaneManager(graph);

	// Creates a stack depending on the orientation of the swimlane
	var layout = new mxStackLayout(graph, false);

	// Makes sure all children fit into the parent swimlane
	layout.resizeParent = true;

	// Applies the size to children if parent size changes
	layout.fill = true;

	// Only update the size of swimlanes
	layout.isVertexIgnored = function(vertex) {
		return !graph.isSwimlane(vertex);
	}

	// Keeps the lanes and pools stacked
	var layoutMgr = new mxLayoutManager(graph);

	layoutMgr.getLayout = function(cell) {
		if (!model.isEdge(cell)
				&& graph.getModel().getChildCount(cell) > 0
				&& (model.getParent(cell) == model.getRoot() || graph
						.isPool(cell))) {
			layout.fill = graph.isPool(cell);

			return layout;
		}

		return null;
	};
	// ////////////////////////////////////////////////////////////

	// Contains the main graph instance inside the given panel
	graph.init(this.diagramContainer);
	//graph.refresh();

	// Enables scrollbars and sets cursor style for the container
	graph.container.setAttribute('tabindex', '0');
	graph.container.style.overflow = (touchStyle) ? 'hidden' : 'auto';
	graph.container.style.cursor = 'default';
	// graph.container.style.height = '625px';
	graph.container.style.backgroundImage = 'url(' + IMAGE_PATH + '/grid.gif)';
	graph.container.focus();

	// Keeps graph container focused on mouse down
	var graphFireMouseEvent = graph.fireMouseEvent;
	graph.fireMouseEvent = function(evtName, me, sender) {
		if (evtName == mxEvent.MOUSE_DOWN) {
			//this.container.focus();
			//this.container.focus();
		}

		graphFireMouseEvent.apply(this, arguments);
	};

	// Configures automatic expand on mouseover
	//graph.popupMenuHandler.autoExpand = true;

	// Installs context menu
//	graph.popupMenuHandler.factoryMethod = mxUtils.bind(this, function(menu,
//					cell, evt) {
//				this.menus.createPopupMenu(menu, cell, evt);
//			});

	// Initializes the outline
	document.body.appendChild(this.outlineContainer);
	$(this.outlineContainer).hide();
	editor.outline.init(this.outlineContainer);
    // editor.outline.init(this.diagramContainer);
	// Hides context menu
	graph.popupMenuHandler.hideMenu();
	var md = (mxClient.IS_TOUCH) ? 'touchstart' : 'mousedown';
	mxEvent.addListener(document, md, mxUtils.bind(this, function(evt) {
						graph.popupMenuHandler.hideMenu();
					}));

	// Adds gesture handling (pinch to zoom)
	if (mxClient.IS_TOUCH) {
		mxEvent.addListener(graph.container, 'gesturechange', mxUtils.bind(
						this, function(evt) {
							graph.view.getDrawPane().setAttribute('transform',
									'scale(' + evt.scale + ')');
							graph.view.getOverlayPane().style.visibility = 'hidden';
						}));

		mxEvent.addListener(graph.container, 'gestureend', mxUtils.bind(this,
						function(evt) {
							graph.view.getDrawPane()
									.removeAttribute('transform');
							graph.zoomToCenter = true;
							graph.zoom(evt.scale);
							graph.view.getOverlayPane().style.visibility = 'visible';
						}));
	}

	// Create handler for key events
	//var keyHandler = this.createKeyHandler(editor);

	// Getter for key handler
//	this.getKeyHandler = function() {
//		return keyHandler;
//	};


	// Updates the editor UI after the window has been resized
	mxEvent.addListener(window, 'resize', mxUtils.bind(this, function() {
				//this.refresh();
				graph.sizeDidChange();
					// this.editor.outline.update(false);
					// this.editor.outline.outline.sizeDidChange();
				}));

	// Updates action and menu states
	//this.init();
	//this.open();

};

/**
 * Specifies the size of the split bar.
 */
// EditorUi.prototype.splitSize = (mxClient.IS_TOUCH) ? 16 : 8;
EditorUi.prototype.splitSize = 0;
/**
 * Specifies the height of the menubar. Default is 34.
 */
// EditorUi.prototype.menubarHeight = 34;
/**
 * Specifies the height of the toolbar. Default is 46.
 */
// EditorUi.prototype.toolbarHeight = 40;
/**
 * Specifies the height of the footer. Default is 28.
 */
// EditorUi.prototype.footerHeight = 0;
/**
 * Specifies the position of the horizontal split bar. Default is 190.
 */

// EditorUi.prototype.hsplitPosition = 46;
/**
 * Specifies the position of the vertical split bar. Default is 190.
 */
// EditorUi.prototype.vsplitPosition = 60;
/**
 * Installs the listeners to update the action states.
 */
EditorUi.prototype.init = function() {
	// Updates action states
	this.addUndoListener();
	this.addSelectionListener();

	// Overrides clipboard to update paste action state
	var paste = this.actions.get('paste');

	var updatePaste = function() {
		paste.setEnabled(!mxClipboard.isEmpty());
	};

	var mxClipboardCut = mxClipboard.cut;
	mxClipboard.cut = function() {
		mxClipboardCut.apply(this, arguments);
		updatePaste();
	};

	var mxClipboardCopy = mxClipboard.copy;
	mxClipboard.copy = function() {
		mxClipboardCopy.apply(this, arguments);
		updatePaste();
	};
};

/**
 * Hook for allowing selection and context menu for certain events.
 */
EditorUi.prototype.isSelectionAllowed = function(evt) {
	return false;
};

/**
 * Updates the states of the given undo/redo items.
 */
EditorUi.prototype.addUndoListener = function() {
	var undo = this.actions.get('undo');
	var redo = this.actions.get('redo');

	var undoMgr = this.editor.undoManager;

	var undoListener = function() {
		undo.setEnabled(undoMgr.canUndo());
		redo.setEnabled(undoMgr.canRedo());
	};

	undoMgr.addListener(mxEvent.ADD, undoListener);
	undoMgr.addListener(mxEvent.UNDO, undoListener);
	undoMgr.addListener(mxEvent.REDO, undoListener);
	undoMgr.addListener(mxEvent.CLEAR, undoListener);

	// Updates the button states once
	undoListener();
};

/**
 * Updates the states of the given toolbar items based on the selection.
 */
EditorUi.prototype.addSelectionListener = function() {
	var selectionListener = mxUtils.bind(this, function() {
		var graph = this.editor.graph;
		var selected = !graph.isSelectionEmpty();
		var vertexSelected = false;
		var edgeSelected = false;

		var cells = graph.getSelectionCells();

		if (cells != null) {
			for (var i = 0; i < cells.length; i++) {
				var cell = cells[i];

				if (graph.getModel().isEdge(cell)) {
					edgeSelected = true;
				}

				if (graph.getModel().isVertex(cell)) {
					vertexSelected = true;
				}

				if (edgeSelected && vertexSelected) {
					break;
				}
			}
		}

		// Updates action states
		var actions = ['cut', 'copy', 'delete', 'duplicate', 'bold', 'italic',
				'style', 'fillColor', 'gradientColor', 'underline',
				'fontColor', 'strokeColor', 'backgroundColor', 'borderColor',
				'toFront', 'toBack', 'dashed', 'rounded', 'shadow', 'rotate',
				'autosize'];

		for (var i = 0; i < actions.length; i++) {
			this.actions.get(actions[i]).setEnabled(selected);
		}

		this.actions.get('rotation').setEnabled(vertexSelected);
		this.actions.get('group').setEnabled(graph.getSelectionCount() > 1);
		this.actions.get('ungroup')
				.setEnabled(graph.getSelectionCount() == 1
						&& graph.getModel().getChildCount(graph
								.getSelectionCell()) > 0);
		var oneVertexSelected = vertexSelected
				&& graph.getSelectionCount() == 1;
		this.actions.get('removeFromGroup').setEnabled(oneVertexSelected
				&& graph.getModel().isVertex(graph.getModel().getParent(graph
						.getSelectionCell())));

		// Updates menu states
//		var menus = ['fontFamily', 'fontSize', 'alignment', 'position', 'text',
//				'format', 'arrange', 'linewidth', 'spacing', 'gradient'];
		var menus = ['fontFamily', 'fontSize', 'alignment', 'position', 'text',
				'format', 'linewidth', 'spacing', 'gradient'];

		for (var i = 0; i < menus.length; i++) {
			this.menus.get(menus[i]).setEnabled(selected);
		}

		menus = ['line', 'lineend', 'linestart'];

		for (var i = 0; i < menus.length; i++) {
			this.menus.get(menus[i]).setEnabled(edgeSelected);
		}

		this.actions.get('setAsDefaultEdge').setEnabled(edgeSelected);

		this.menus.get('align').setEnabled(graph.getSelectionCount() > 1);
		this.menus.get('direction').setEnabled(vertexSelected
				|| (edgeSelected && graph.isLoop(graph.view.getState(graph
						.getSelectionCell()))));
		this.menus.get('navigation').setEnabled(graph.foldingEnabled
				&& ((graph.view.currentRoot != null) || (graph
						.getSelectionCount() == 1 && graph.isValidRoot(graph
						.getSelectionCell()))));
		this.actions.get('home').setEnabled(graph.view.currentRoot != null);
		this.actions.get('exitGroup')
				.setEnabled(graph.view.currentRoot != null);
		var groupEnabled = graph.getSelectionCount() == 1
				&& graph.isValidRoot(graph.getSelectionCell());
		this.actions.get('enterGroup').setEnabled(groupEnabled);
		this.actions.get('expand').setEnabled(groupEnabled);
		this.actions.get('collapse').setEnabled(groupEnabled);
		this.actions.get('editLink').setEnabled(graph.getSelectionCount() == 1);
		this.actions.get('openLink').setEnabled(graph.getSelectionCount() == 1
				&& graph.getLinkForCell(graph.getSelectionCell()) != null);
	});

	this.editor.graph.getSelectionModel().addListener(mxEvent.CHANGE,
			selectionListener);
	selectionListener();
};

/**
 * Refreshes the viewport.
 */
EditorUi.prototype.refresh = function() {
	var quirks = mxClient.IS_IE
			&& (document.documentMode == null || document.documentMode == 5);
	var w = this.container.clientWidth;
	var h = this.container.clientHeight;

	if (this.container == document.body) {
		w = document.body.clientWidth || document.documentElement.clientWidth;
		h = (quirks)
				? document.body.clientHeight
						|| document.documentElement.clientHeight
				: document.documentElement.clientHeight;
	}

	// var effHsplitPosition = Math.max(0, Math.min(this.hsplitPosition, w -
	// this.splitSize - 20));
	// var effVsplitPosition = Math.max(0, Math.min(this.vsplitPosition, h -
	// this.menubarHeight - this.toolbarHeight - this.footerHeight -
	// this.splitSize - 1));
	/*
	 * this.menubarContainer.style.height = this.menubarHeight + 'px';
	 * this.toolbarContainer.style.top = this.menubarHeight + 'px';
	 * this.toolbarContainer.style.height = this.toolbarHeight + 'px';
	 * this.sidebarContainer.style.top = (this.menubarHeight +
	 * this.toolbarHeight) + 'px'; this.sidebarContainer.style.width =
	 * effHsplitPosition + 'px';
	 */
	// this.outlineContainer.style.width = effHsplitPosition + 'px';
	// this.outlineContainer.style.height = effVsplitPosition + 'px';
	// this.outlineContainer.style.bottom = this.footerHeight + 'px';
	this.diagramContainer.style.left = '0px';// (effHsplitPosition +
												// this.splitSize) + 'px';
	this.diagramContainer.style.top = '50px'; // this.sidebarContainer.style.top;
	this.hintsContainer.style.width = w + 'px';
	this.hintsContainer.style.left = '0px';
	this.hintsContainer.style.top = '0px';
	this.hintsContainer.style.height = '30px';
	// this.footerContainer.style.height = this.footerHeight + 'px';
	// this.hsplit.style.top = this.sidebarContainer.style.top;
	// this.hsplit.style.bottom = this.outlineContainer.style.bottom;
	// this.hsplit.style.bottom=this.footerHeight + 'px';
	// this.hsplit.style.left = effHsplitPosition + 'px';
	// this.vsplit.style.width = this.sidebarContainer.style.width;
	// this.vsplit.style.bottom = (effVsplitPosition + this.footerHeight) +
	// 'px';

	if (quirks) {
		// //this.menubarContainer.style.width = w + 'px';
		// this.toolbarContainer.style.width =
		// this.menubarContainer.style.width;
		// var sidebarHeight = (h - effVsplitPosition - this.splitSize -
		// this.footerHeight - this.menubarHeight - this.toolbarHeight);
		// var sidebarHeight = (h - this.menubarHeight - this.toolbarHeight);
		// this.sidebarContainer.style.height = sidebarHeight + 'px';
		this.diagramContainer.style.width = w + 'px';
		// var diagramHeight = h;//(h - this.footerHeight - this.menubarHeight -
		// this.toolbarHeight);
		this.diagramContainer.style.height = (h-50) + 'px';
		// this.footerContainer.style.width = w + 'px';
		// this.hsplit.style.height = diagramHeight + 'px';
	} else {
		// this.sidebarContainer.style.bottom = (effVsplitPosition +
		// this.splitSize + this.footerHeight) + 'px';
		// this.sidebarContainer.style.bottom = this.footerHeight + 'px';
		// this.diagramContainer.style.bottom =
		// this.outlineContainer.style.bottom;
		this.diagramContainer.style.width = w + 'px';
		this.diagramContainer.style.height = (h-50) + 'px';// this.hsplit.style.bottom;
	}
};

/**
 * Creates the required containers.
 */
EditorUi.prototype.createDivs = function() {
	// this.menubarContainer = this.createDiv('geMenubarContainer');
	// this.toolbarContainer = this.createDiv('geToolbarContainer');
	this.sidebarContainer = this.createDiv('geSidebarContainer');
	this.outlineContainer = this.createDiv('geOutlineContainer');
	//this.diagramContainer = this.createDiv('geDiagramContainer');
	// this.footerContainer = this.createDiv('geFooterContainer');
	// this.hsplit = this.createDiv('geHsplit');
	// this.vsplit = this.createDiv('geVsplit');

	// Sets static style for containers
	/*
	 * this.menubarContainer.style.top = '0px'; this.menubarContainer.style.left =
	 * '0px'; this.menubarContainer.style.right = '0px';
	 * this.toolbarContainer.style.left = '0px';
	 * this.toolbarContainer.style.right = '0px';
	 * this.sidebarContainer.style.left = '0px';
	 */
	//this.outlineContainer.style.left = '0px';
	/*
	 * this.diagramContainer.style.right = '0px';
	 * this.footerContainer.style.left = '0px'; this.footerContainer.style.right =
	 * '0px'; this.footerContainer.style.bottom = '0px'; this.vsplit.style.left =
	 * '0px'; this.vsplit.style.height = this.splitSize + 'px';
	 * this.hsplit.style.width = this.splitSize + 'px';
	 */
};





/**
 * Creates a new sidebar for the given container.
 */
EditorUi.prototype.createSidebar = function(container) {
	return new Sidebar(this, container);
};


/**
 * Creates the actual toolbar for the toolbar container.
 */
EditorUi.prototype.createDiv = function(classname) {
	var elt = document.createElement('div');
	elt.className = classname;

	return elt;
};



/**
 * Executes the given layout.
 */
EditorUi.prototype.executeLayout = function(layout, animate, ignoreChildCount) {
	var graph = this.editor.graph;
	var cell = graph.getSelectionCell();

	graph.getModel().beginUpdate();
	try {
		layout.execute(graph.getDefaultParent(), cell);
	} catch (e) {
		throw e;
	} finally {
		// Animates the changes in the graph model except
		// for Camino, where animation is too slow
		if (animate && navigator.userAgent.indexOf('Camino') < 0) {
			// New API for animating graph layout results asynchronously
			var morph = new mxMorphing(graph);
			morph.addListener(mxEvent.DONE, mxUtils.bind(this, function() {
								graph.getModel().endUpdate();
							}));

			morph.startAnimation();
			
		} else {
			graph.getModel().endUpdate();
		}
	}
};

/**
 * Creates the keyboard event handler for the current graph and history.
 */
EditorUi.prototype.createKeyHandler = function(editor) {
	var graph = this.editor.graph;
	var keyHandler = new mxKeyHandler(graph);

	// Routes command-key to control-key on Mac
	keyHandler.isControlDown = function(evt) {
		return mxEvent.isControlDown(evt) || (mxClient.IS_MAC && evt.metaKey);
	};

	// Helper function to move cells with the cursor keys
	function nudge(keyCode) {
		if (!graph.isSelectionEmpty()) {
			var dx = 0;
			var dy = 0;

			if (keyCode == 37) {
				dx = -1;
			} else if (keyCode == 38) {
				dy = -1;
			} else if (keyCode == 39) {
				dx = 1;
			} else if (keyCode == 40) {
				dy = 1;
			}

			graph.moveCells(graph.getSelectionCells(), dx, dy);
			graph.scrollCellVisible(graph.getSelectionCell());
		}
	};

	// Binds keystrokes to actions
	var bindAction = mxUtils.bind(this, function(code, control, key, shift) {
				var action = this.actions.get(key);

				if (action != null) {
					var f = function() {
						if (action.enabled) {
							action.funct();
						}
					};

					if (control) {
						if (shift) {
							keyHandler.bindControlShiftKey(code, f);
						} else {
							keyHandler.bindControlKey(code, f);
						}
					} else {
						if (shift) {
							keyHandler.bindShiftKey(code, f);
						} else {
							keyHandler.bindKey(code, f);
						}
					}
				}
			});

	var ui = this;
	var keyHandleEscape = keyHandler.escape;
	keyHandler.escape = function(evt) {
		ui.hideDialog();
		keyHandleEscape.apply(this, arguments);
	};

	// Ignores enter keystroke. Remove this line if you want the
	// enter keystroke to stop editing.
	keyHandler.enter = function() {
	};
	keyHandler.bindKey(8, function() {
				graph.foldCells(true);
			}); // Backspace
	keyHandler.bindKey(13, function() {
				graph.foldCells(false);
			}); // Enter
	keyHandler.bindKey(33, function() {
				graph.exitGroup();
			}); // Page Up
	keyHandler.bindKey(34, function() {
				graph.enterGroup();
			}); // Page Down
	keyHandler.bindKey(36, function() {
				graph.home();
			}); // Home
	keyHandler.bindKey(35, function() {
				graph.refresh();
			}); // End
	keyHandler.bindKey(37, function() {
				nudge(37);
			}); // Left arrow
	keyHandler.bindKey(38, function() {
				nudge(38);
			}); // Up arrow
	keyHandler.bindKey(39, function() {
				nudge(39);
			}); // Right arrow
	keyHandler.bindKey(40, function() {
				nudge(40);
			}); // Down arrow
	keyHandler.bindKey(113, function() {
				graph.startEditingAtCell();
			});
	bindAction(46, false, 'delete'); // Delete
	bindAction(82, true, 'rotate'); // Ctrl+R
	bindAction(83, true, 'save'); // Ctrl+S
	bindAction(83, true, 'saveAs', true); // Ctrl+Shift+S
	bindAction(107, false, 'zoomIn'); // Add
	bindAction(109, false, 'zoomOut'); // Subtract
	bindAction(65, true, 'selectAll'); // Ctrl+A
	bindAction(86, true, 'selectVertices', true); // Ctrl+Shift+V
	bindAction(69, true, 'selectEdges', true); // Ctrl+Shift+E
	bindAction(69, true, 'export'); // Ctrl+Shift+E
	bindAction(66, true, 'toBack'); // Ctrl+B
	bindAction(70, true, 'toFront'); // Ctrl+F
	bindAction(68, true, 'duplicate'); // Ctrl+D
	bindAction(90, true, 'undo'); // Ctrl+Z
	bindAction(89, true, 'redo'); // Ctrl+Y
	bindAction(88, true, 'cut'); // Ctrl+X
	bindAction(67, true, 'copy'); // Ctrl+C
	bindAction(81, true, 'connect'); // Ctrl+Q
	bindAction(86, true, 'paste'); // Ctrl+V
	bindAction(71, true, 'group'); // Ctrl+G
	bindAction(71, true, 'grid', true); // Ctrl+Shift+G
	bindAction(85, true, 'ungroup'); // Ctrl+U
	bindAction(112, false, 'about'); // F1

	return keyHandler;
};

EditorUi.prototype.toggleOutline = function() {
	if (this.outline)
		this.outline.setVisible(!this.outline.isVisible());
	else
		this.showOutline();
}

EditorUi.prototype.showOutline = function() {
	if (!this.outline) {
		var div = document.createElement("div");
		div.style.overflow = "hidden";
		div.style.width = "100%";
		div.style.height = "100%";
		div.style.background = "white";
		div.style.cursor = "move";
		var win = new mxWindow('缩略图', div, 200, 200, 200, 200, false)
		var outline = new mxOutline(this.editor.graph, div);
		win.setClosable(true);
		win.setResizable(true);
		win.destroyOnClose = false;
		win.addListener(mxEvent.RESIZE_END, function() {
					outline.update()
				});
		this.outline = win;
		this.outline.outline = outline;
	}
	this.outline.setVisible(true);
	this.outline.outline.update(true);
}

EditorUi.prototype.glitterActiveActivities = function() {
	viewer=this;
	setInterval("glitter()",1000);
    
}
glitter = function() {	
	var graph = viewer.editor.graph;
	var model = graph.getModel();
	model.beginUpdate();
	try {
		var activities = viewer.getAllActivities();
		$(activities).each(function() {
					var id = this.getId();
					var state = this.getAttribute("state");
					if(state=="活动"){
						if(freshFlag=="0")
						viewer.ashingCell( id,graph);
						if(freshFlag=="1")
						viewer.relightCell( id,graph);
					}
				});
	} finally {
		model.endUpdate();
	}
	 if(freshFlag=="0") freshFlag="1";
     else freshFlag="0";
}

EditorUi.prototype.showTraceGraph = function(procInstId) {

	var info = new EiInfo();
	info.set('ProcessInstanceId', procInstId);
	var viewer = this;

	EiCommunicator.send('EWPI00', 'getProcessInfoById', info, {
		onSuccess : function(outInfo) {
			var xml = outInfo.get('XML');

			viewer.loadWorkflowXml(xml);
			var graph = viewer.editor.graph;
			// Shared variable between child function scopes
			// aka "private" variable
			var currentPermission = null;

			var apply = function(permission) {
				graph.clearSelection();
				permission.apply(graph);
				graph.setEnabled(true);
				graph.setTooltips(true);

				// Updates the icons on the shapes - rarely
				// needed and very slow for large graphs
				graph.refresh();
				currentPermission = permission;
			};
			apply(new Permission());
			// ///////////////////////////
			// Extends hook functions to use permission object. This could
			// be done by assigning the respective switches (eg.
			// setMovable), but this approach is more flexible, doesn't
			// override any existing behaviour or settings, and allows for
			// dynamic conditions to be used in the functions. See the
			// specification for more functions to extend (eg.
			// isSelectable).
			var oldDisconnectable = graph.isCellDisconnectable;
			graph.isCellDisconnectable = function(cell, terminal, source) {
				return oldDisconnectable.apply(this, arguments)
						&& currentPermission.editEdges;
			};

			var oldTerminalPointMovable = graph.isTerminalPointMovable;
			graph.isTerminalPointMovable = function(cell) {
				return oldTerminalPointMovable.apply(this, arguments)
						&& currentPermission.editEdges;
			};

			var oldBendable = graph.isCellBendable;
			graph.isCellBendable = function(cell) {
				return oldBendable.apply(this, arguments)
						&& currentPermission.editEdges;
			};

			var oldLabelMovable = graph.isLabelMovable;
			graph.isLabelMovable = function(cell) {
				return oldLabelMovable.apply(this, arguments)
						&& currentPermission.editEdges;
			};

			var oldMovable = graph.isCellMovable;
			graph.isCellMovable = function(cell) {
				return oldMovable.apply(this, arguments)
						&& currentPermission.editVertices;
			};

			var oldResizable = graph.isCellResizable;
			graph.isCellResizable = function(cell) {
				return oldResizable.apply(this, arguments)
						&& currentPermission.editVertices;
			};

			var oldEditable = graph.isCellEditable;
			graph.isCellEditable = function(cell) {
				return oldEditable.apply(this, arguments)
						&& (this.getModel().isVertex(cell) && currentPermission.editVertices)
						|| (this.getModel().isEdge(cell) && currentPermission.editEdges);
			};

			var oldDeletable = graph.isCellDeletable;
			graph.isCellDeletable = function(cell) {
				return oldDeletable.apply(this, arguments)
						&& (this.getModel().isVertex(cell) && currentPermission.editVertices)
						|| (this.getModel().isEdge(cell) && currentPermission.editEdges);
			};

			var oldCloneable = graph.isCellCloneable;
			graph.isCellCloneable = function(cell) {
				return oldCloneable.apply(this, arguments)
						&& currentPermission.cloneCells;
			};

			// ///////////////////////////
			// select only
			apply(new Permission(false, false, false, false, false));

			// ////////////////////////////////////////////////////
			var count = outInfo.get('count');
			var id = "";
			var name = "";
			var adi = "";
			var state = "";
			var transName = "";
			var startTime="";
			var endTime="";
			var duration="";
			var readFinished="";
			var procInstId = "";
			var model = graph.getModel();
			model.beginUpdate();
			try {
				var actids = [];
				for (var i = 0; i < count; i++) {
					id = outInfo.get("ai" + i);
					adi = outInfo.get("adi" + i);
					name = outInfo.get("a" + i);
					state = outInfo.get("as" + i);
					type = outInfo.get("at" + i);

					var transid = "t" + i;


					if(outInfo.get(transid)==undefined){
					}else{
                        transName = outInfo.get(transid);
					}
					startTime=outInfo.get("st" + i);
					endTime=outInfo.get("et" + i);
					duration=outInfo.get("d" + i);
					readFinished=outInfo.get("r" + i);
					procInstId = outInfo.get("proc" + i);
					var transids = viewer.highlightCell(id, adi, state, transName,
							graph,startTime,endTime,duration,readFinished,procInstId);
					if (transids.length >0)
					for(var j=0;j<transids.length;j++)actids.push(transids[j]);
					actids.push(adi);
				}
				
				var activities = viewer.getAllActivities();
				$(activities).each(function() {
							var id = this.getId();
							if (!actids.in_array(id)) {
								viewer.ashingCell( id,graph);
							}
						});
			} finally {
				model.endUpdate();
			}
			// ////////////////////////////////////////////////////
			graph.setGridEnabled(false);
			viewer.editor.updateGraphComponents();

		},
		onFail : function(message) {
			alert(message);
		}
	}, false, false);
	this.glitterActiveActivities();
}

Array.prototype.in_array = function(e) {
	for (i = 0; i < this.length; i++) {
		if (this[i] == e)
			return true;
	}
	return false;
}

EditorUi.prototype.loadWorkflowXml = function(xml) {
	var doc = DomHelper.parseXml(xml);
	if (doc.documentElement.nodeName != 'mxGraphModel'
			&& doc.documentElement.nodeName != 'WorkflowProcess') {
		alert('XML解析失败！');
		return;
	}
	this.editor.setWorkflowXml(doc.documentElement);
};

EditorUi.prototype.dialog = function(title, form, options) {
	var src = 'http://' + window.location.host + window.location.pathname
			+ '?efFormEname=' + form;
	if (options && options.params)
		src += '&' + options.params;
	$('body').append($('<div style="display:none"/>').attr({
				id : form,
				title : title
			}));
	$('#' + form).dialog({
				autoOpen : true,
				modal : true,
				height : options && options.height ? options.height : 600,
				width : options && options.width ? options.width : 800,
				zIndex : 9999,
				resizable : false,
				close : function(event, ui) {
					$(event.target).dialog("destroy").remove();
					if (options && options.onclose)
						options.onclose(event, ui);
				}
			});

	// IE9 Iframe在DOM移动一次 加载js就会失败
	var frame = $('<iframe frameborder= "0" />').attr('src', src).css({
				height : '100%',
				width : '100%'
			});
	$('#' + form).append(frame);
};
/**
 * 对未经过的流程活动及转移灰化
 * @param {} id
 * @param {} graph
 */
EditorUi.prototype.ashingCell =function(id,graph){
	var model = graph.getModel();
	var cell = model.getCell(id);
	//银色：#e6e6e6	
		var displayName = cell.getAttribute("DisplayName");
    if (!displayName||displayName && displayName.indexOf('跳转') == -1	&& displayName.indexOf('回退') == -1&& displayName.indexOf('审批结束') == -1) {
        graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, '#e6e6e6', [cell]);//银色：#e6e6e6
        graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#e6e6e6', [cell]);
    }
};

EditorUi.prototype.relightCell =function(id,graph){
	var model = graph.getModel();
	var cell = model.getCell(id);
	if(model.isVertex(cell)){
	graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, '#576bff', [cell]);//蓝色
	graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#a3a3a3',[cell]);//灰色边框：#a3a3a3	
	}
};

EditorUi.prototype.addOverlays=function(graph, cell, readFinsih)
{
	var overlay;
	if(readFinsih==false){
	overlay = new mxCellOverlay(new mxImage(IMAGE_PATH+"/eye-grey.png", 32, 32), '所有待办任务未阅读!');	
	overlay.addListener(mxEvent.CLICK, mxUtils.bind(this, function(sender, evt)
	{
		//addChild(graph, cell);
		alert("所有待办任务未阅读");
	}));	
	}
	else{
		overlay = new mxCellOverlay(new mxImage(IMAGE_PATH+"/eye-blue.png", 32, 32), '至少一个待办任务已阅读!');
		
		overlay.addListener(mxEvent.CLICK, mxUtils.bind(this, function(sender, evt)
		{
			//addChild(graph, cell);
			alert("至少一个待办任务已阅读!");
		}));		
	}
	overlay.cursor = 'hand';
	overlay.offset = new mxPoint(-4, -50);
	overlay.align = mxConstants.ALIGN_RIGHT;
	graph.addCellOverlay(cell, overlay);
};
/**
 * 对已经过的流程活动及转移着色
 * @param {} instid
 * @param {} id
 * @param {} state
 * @param {} transName
 * @param {} graph
 * @param {} startTime
 * @param {} endTime
 * @param {} duration
 * @return {}
 */
EditorUi.prototype.highlightCell = function(instid, id, state, transName, graph,startTime,endTime,duration,readFinished,procInstId) {
	var transids = [];
	var model = graph.getModel();
	var cell = model.getCell(id);   
	// Updates the cell color and adds some tooltip information
	if (cell == null)
		return transids;
	var tagName = cell.value.tagName;
	 var displayName=cell.value.getAttribute("DisplayName")
	var stateDisplayName = "";
    if (tagName == "Start")
        state = "ended";
	if (state == "active")
		stateDisplayName = "活动";
	if (state == "suspended")
		stateDisplayName = "挂起";
	if (state == "ended")
		stateDisplayName = "完成";
	//设置活动实例信息，悬浮显示
	if (instid != ""){
			cell.value.setAttribute("instid", instid);
			cell.value.setAttribute("startTime", startTime);
			cell.value.setAttribute("endTime", endTime);
			cell.value.setAttribute("duration", duration);
			cell.value.setAttribute("state", stateDisplayName);
			cell.value.setAttribute("procInstId", procInstId);
			
		}
	 if (tagName == 'End') {		
		return transids;
	   }

		// Changes the cell color for the known states
	   //1. 对活动实例进行着色
		//1.1活动实例为活动状态，着蓝色#576bff
		if (state == 'active') {
			// if (tagName =='InclusiveGateway') {
			// 	return transids;
			//    }
			graph.setTooltips(true);
			graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, '#576bff', [cell]);
			graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#a3a3a3',
					[cell]);//灰色边框：#a3a3a3

			//if(readFinished=='true')
			//this.addOverlays(graph, cell, true);
			//else
			//	this.addOverlays(graph, cell, false);
//			graph.setCellWarning(cell,"ok",graph.warningImage,false);
			
		}
		//1.2活动实例为挂起状态，着黄色#fdeb12
		else if (state == 'suspended') {
			graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, '#FF2D2D', [cell]);
			graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#FF2D2D',
					[cell]);
		}
		
		//1.3活动实例为完成状态活动	
		//1.3.1.正常流转，设置颜色为绿色#61d855
		//1.3.2.回退或转移，设置颜色为红色#fb0211
		//1.3.3.强制终止，设置为红色#fb0211
		if (state == 'ended') {		
			var isReturnTo=(transName.indexOf('Return to:')>-1);
			var isJumpTo=(transName.indexOf('Jump to:')>-1);
			var isUndo=(transName.indexOf('Undo to:')>-1);
			var isFork=(cell.value.tagName=="Fork");
            var isForceEnd=(transName.indexOf('Force end:')>-1);
			//正常流转，设置颜色为绿色				
			graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, '#61d855', [cell]);
			graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#a3a3a3',
					[cell]);
			//强制终止，设置为红色#fb0211
			// if(isForceEnd){
			//   graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, '#fb0211', [cell]);
			//   graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#a3a3a3',	[cell]);
			// }
			
			//回退或转移，设置颜色为红色			
            if (isReturnTo || isJumpTo || isForceEnd) {
			var viewer = this;
			var actId = null;
			var activities = this.getAllActivities();

			var tnArr = transName.split(":");
			var actName = tnArr[2];
			var i = 0;
			// 从第一个位置即索引为0的位置开始查找不是" "空格的字符(串)
			for (; i < actName.length && actName.charAt(i) == " "; i++);
			actName = actName.substring(i, actName.length);
			// alert(actName);

			$(activities).each(function() {
						if (this.value.getAttribute("Name") == actName) {
							actId = this.getId();
						}
					});

			// /添加跳转线
			var doc = mxUtils.createXmlDocument();
			var parent = graph.getDefaultParent();
			var jumpTargetCell = model.getCell(actId);
			var transtyle = "strokeColor=#fb0211;edgeStyle=entityRelationEdgeStyle;";
			var e1 = null;
			if (isJumpTo) {
				e1 = graph.insertEdge(parent, null, '跳转', cell, jumpTargetCell,
						transtyle);
				e1.value.setAttribute("DisplayName", '跳转');
				e1.value.setAttribute("Name", '跳转');
			}
			if (isReturnTo) {
				e1 = graph.insertEdge(parent, null, '回退', cell, jumpTargetCell,
						transtyle);
				e1.value.setAttribute("DisplayName", '回退');
				e1.value.setAttribute("Name", '回退');
			}
			if (isForceEnd) {
				e1 = graph.insertEdge(parent, null, '审批结束', cell, jumpTargetCell, transtyle);
				e1.value.setAttribute("DisplayName", '审批结束');
				e1.value.setAttribute("Name", '审批结束');
			}
            //#fb0211
				graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, '#fb0211', [e1]);  //设置线条的颜色为红色
				graph.setCellStyles(mxConstants.STYLE_STROKEWIDTH, '2', [e1]); //设置线条的的宽度
				graph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ORTHOGONAL, [e1]); //经过调试得到的回退线类型，若要显示成图中效果则该类型不可更改
				graph.setCellStyles(mxConstants.STYLE_CURVED, '2', [e1]); //控制回退线是否有弧度
				graph.setCellStyles(mxConstants.STYLE_EXIT_X, '0', [e1]); //回退线起点坐标Ｘ轴相关参数
				graph.setCellStyles(mxConstants.STYLE_EXIT_Y, '50', [e1]); //回退线起点坐标Ｙ轴相关参数
				graph.setCellStyles(mxConstants.STYLE_EXIT_PERIMETER, '1', [e1]); //回退线起点坐标相关参数
				graph.setCellStyles(mxConstants.STYLE_ENTRY_X, '0', [e1]); //回退线终点Ｘ轴坐标相关参数
				graph.setCellStyles(mxConstants.STYLE_ENTRY_Y, '50', [e1]); //回退线终点Ｙ轴坐标相关参数
				graph.setCellStyles(mxConstants.STYLE_ENTRY_PERIMETER, '1', [e1]); //回退线终点坐标相关参数
				graph.setCellStyles(mxConstants.STYLE_ENDSIZE, '1', [e1]); //回退线尾部箭头大小
				graph.setCellStyles(mxConstants.STYLE_FONTCOLOR, '#fb0211', [e1]); //设置线条上"回退"的字体颜色为红色
				graph.setCellStyles(mxConstants.STYLE_FONTSTYLE, '1', [e1]); //设置线条上"回退"的字体类型
		}
	   }
					
			//2. 对活动实例的连线进行着色
			var edgeCount = cell.getEdgeCount();
			for (var i = 0; i < edgeCount; i++) {
				var edge = cell.getEdgeAt(i);
				if (edge.target == cell)
					continue;
				if (edge.getAttribute("Name") == transName||cell.value.tagName=='Fork') {
					transids.push(edge.getId()) ;
					// 绿色：#006600
					graph.setCellStyles(mxConstants.STYLE_STROKECOLOR,
							'#006600', [edge]);
					graph.setCellStyles(mxConstants.STYLE_STROKEWIDTH, '2',
							[edge]);
					graph.setCellStyles(mxConstants.STYLE_FONTSTYLE, '1',
							[edge]);
					edge.value.setAttribute("DisplayName",edge.value.getAttribute("DisplayName"));
				}				
			}		
	return transids;
};

EditorUi.prototype.getAllActivities = function() {
	var graph = this.editor.graph;
	var root = null;
	root = graph.getCurrentRoot();
	if (root == null) {
		root = graph.getModel().getRoot();
	}
	var model = graph.getModel();
	var filter = function(cell) {
		return true;
		// var tagName=cell.value.tagName;
		// return model.isVertex(cell)&&(tagName=='Start'||tagName=='Manual');
	}
	var acts = [];

	var rootChilds = model.getChildCells(model.getCell("1"));
	$(rootChilds).each(function() {
		var tagName = this.value.tagName;
		if (model.isVertex(this) && tagName == 'Swimlane') {
			var slChilds = model.filterCells(model.getChildCells(this), filter);
			$(slChilds).each(function() {
						acts.push(this);
					});
		}
		// if(model.isVertex(this)&&(tagName=='Start'||tagName=='Manual'))
		acts.push(this);
	});

	return acts;
};

/**
 * Creates an overlay object using the given tooltip and text for the alert
 * window which is being displayed on click.
 */
EditorUi.prototype.createOverlay = function(image, tooltip) {
	var overlay = new mxCellOverlay(image, tooltip);

	// Installs a handler for clicks on the overlay
	overlay.addListener(mxEvent.CLICK, function(sender, evt) {
				mxUtils.alert(tooltip + '\n' + 'Last update: ' + new Date());
			});

	return overlay;
};

EditorUi.prototype.createHints = function(){
    var hints = document.createElement('div');
	hints.style.position = 'absolute';
	hints.style.overflow = 'hidden';
	hints.style.width = '850px';
	hints.style.top = '10px';
	hints.style.height = '30px';
	hints.style.left = '20px';

	hints.style.background = 'white';
	hints.style.color = 'black';
	hints.style.fontFamily = '微软雅黑';
	hints.style.fontSize = '12px';
	//hints.style.fontStyle = '1';
	hints.style.padding = '1px';
	hints.style.verticalAlign = 'middle';
	
	//mxUtils.setOpacity(hints, 50);


	var img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/grayline.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 未经过  ');
	
	 img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/greenline.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 已经过  ');
	
	
	
	 img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/redline.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 回退或跳转  ');
	
	
	img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/grayrect.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 未到达活动  ');
	
	img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/bluerect.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 当前活动   ');
	
	img = document.createElement('img');
	img.setAttribute('src',IMAGE_PATH+ "/redrect.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 挂起活动  ');
	
	img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/greenrect.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 已完成活动  ');
	/*
	img = document.createElement('img');
	img.setAttribute('src', IMAGE_PATH+"/redrect.png");
	img.style.width = '36px';
	img.style.height = '20px';
	// img.title = 'Drag this to the diagram to create a new vertex';
	hints.appendChild(img);
	mxUtils.write(hints, ' 强制终止活动  ');	*/
	return hints;
};

function Permission(locked, createEdges, editEdges, editVertices, cloneCells) {
	this.locked = (locked != null) ? locked : false;
	this.createEdges = (createEdges != null) ? createEdges : true;
	this.editEdges = (editEdges != null) ? editEdges : true;;
	this.editVertices = (editVertices != null) ? editVertices : true;;
	this.cloneCells = (cloneCells != null) ? cloneCells : true;;
};

Permission.prototype.apply = function(graph) {
	graph.setConnectable(this.createEdges);
	graph.setCellsLocked(this.locked);
};
